package org.hgvc.webapp.ets.spring.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hgvc.webapp.ets.bo.Agent;
import org.hgvc.webapp.ets.bo.AgentCommission;
import org.hgvc.webapp.ets.bo.Member;
import org.hgvc.webapp.ets.bo.MemberComp;
import org.hgvc.webapp.ets.bo.MemberInd;
import org.hgvc.webapp.ets.bo.Partner;
import org.hgvc.webapp.ets.bo.TerminateLog;
import org.hgvc.webapp.ets.constant.CommonConstant;
import org.hgvc.webapp.ets.constant.MemberConstant;
import org.hgvc.webapp.ets.constant.TerminateConstant;
import org.hgvc.webapp.ets.spring.dao.AgentHbmDao;
import org.hgvc.webapp.ets.spring.dao.MemberHbmDao;
import org.hgvc.webapp.ets.spring.dao.TerminateHbmDao;
import org.jocsb.base.bo.User;
import org.jocsb.base.exception.BaseException;
import org.jocsb.base.util.SpringUtils;

public class TerminateProcServiceImpl implements TerminateProcService{

	private TerminateHbmDao dao;
	private MemberHbmDao memberDao;
	private AgentHbmDao agentDao;
	
	
	private static final Logger log = Logger.getLogger(TerminateProcService.class);
	
	public void terminatePartner(Partner partner,User actionTakenBy)throws BaseException{
		String invMethodName=TerminateProcService.class.getSimpleName()+".terminatePartner()";
		log.debug("invoke "+invMethodName+" partnerName: "+partner.getCompName());
		try{
			partner.setStatus(TerminateConstant.TERMINATED);
			partner.setModifiedBy(actionTakenBy);
			partner.setModifiedDate(new Date());
			dao.update(partner);
			
			saveTerminateLog(TerminateConstant.TERMINATE_TYPE_PARTNER, 
					TerminateConstant.TERMINATE_TYPE_PARTNER+" account is "+TerminateConstant.TERMINATED, 
					partner.getCode()+"/"+partner.getCompName()+"/"+partner.getEmail(),actionTakenBy);
			
			disableUserAccount(TerminateConstant.TERMINATE_TYPE_PARTNER,partner.getRefUser(), actionTakenBy);
			
			cancelMemberBooking(TerminateConstant.TERMINATE_TYPE_PARTNER, partner, actionTakenBy);
			
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.invoke.method", new Object[]{invMethodName}));
		}
	}
	
	public void terminateProspect(Member member,User actionTakenBy)throws BaseException{
		terminateProspectOrMember(member, actionTakenBy, TerminateConstant.TERMINATE_TYPE_PROSPECT);
	}
	
	public void terminateMember(Member member,User actionTakenBy)throws BaseException{
		terminateProspectOrMember(member, actionTakenBy, TerminateConstant.TERMINATE_TYPE_MEMBER);
	}
	
	public void terminateAgent(Agent terminateAgent, Agent newAssignAgent,User actionTakenBy)throws BaseException{
		String invMethodName= TerminateProcService.class.getSimpleName()+".terminateAgent()";
		try{
			terminateAgent.setStatus(TerminateConstant.TERMINATED);
			terminateAgent.setModifiedBy(actionTakenBy);
			terminateAgent.setModifiedDate(new Date());
			dao.update(terminateAgent);
			
			List<AgentCommission> agentCommissionList=agentDao.getAgentCommissionList(terminateAgent);
			for(AgentCommission agentCommission : agentCommissionList){
				
			}
			
			disableUserAccount(TerminateConstant.TERMINATE_TYPE_AGENT, terminateAgent.getRefUser(), actionTakenBy);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.invoke.method", new Object[]{invMethodName}));
		}
	}
	
	private void terminateProspectOrMember(Member member,User actionTakenBy,String terminateType)throws BaseException{
		String invMethodName= TerminateProcService.class.getSimpleName()+".terminateProspectOrMember()";
		try{
			
			member.setStatus(TerminateConstant.TERMINATED);
			member.setModifiedBy(actionTakenBy);
			member.setModifiedDate(new Date());
			dao.update(member);
			
			String accountInfo="";
			if (member.getMemberType().equalsIgnoreCase(CommonConstant.MEMBER_TYPE_IND)){
				MemberInd memberInd = memberDao.getMemberIndByMemberId(member.getMemberId());
				if (memberInd!=null){
					accountInfo = memberInd.getNewIcNo()+"/"+memberInd.getNameAsIcPassport();
				}
				
			}else{//Member Company
				MemberComp memberComp = memberDao.getMemberCompByMemberId(member.getMemberId());
				if (memberComp!=null){
					accountInfo = member.getMemberRegNo()+"/"+member.getName();
				}
			}
			
			saveTerminateLog(terminateType, 
					terminateType+" account is "+TerminateConstant.TERMINATED, 
					accountInfo,actionTakenBy);
			
			disableUserAccount(terminateType,member.getLoginUser(), actionTakenBy);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.invoke.method", new Object[]{invMethodName}));
		}
	}
	
	
	private void disableUserAccount(String invokefromTterminateType,User user,User actionTakenBy)throws BaseException{
	
		String invMethodName=TerminateProcService.class.getSimpleName()+".disableUserAccount()";
		log.debug("invoke "+invMethodName+" userId: "+user.getUsername());
		try{
			user.setStatus(TerminateConstant.DISABLED);
			user.setModifiedBy(actionTakenBy);
			user.setModifiedDate(new Date());
			
			dao.update(user);
			
			saveTerminateLog(invokefromTterminateType, 
					TerminateConstant.DISABLED_TYPE_USER+" account is "+TerminateConstant.DISABLED, 
					user.getUsername(),actionTakenBy);
			
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.invoke.method", new Object[]{invMethodName}));
		}
	}
	
	private void cancelMemberBooking(String invokefromTerminateType,Partner partner,User actionTakenBy)throws BaseException{
		String invMethodName=TerminateProcService.class.getSimpleName()+".cancelMemberBooking()";
		log.debug("invoke "+invMethodName);
		
		log.debug(invMethodName+" : to be implement later");
	}
	
	public void saveTerminateLog(String terminateType,String terminateDesc,String terminateAcctInfo,User actionTakenBy)throws BaseException{
		String invMethodName=TerminateProcService.class.getSimpleName()+".saveTerminateLog()";
		log.debug("invoke "+invMethodName);
		try{
			TerminateLog terminateLog = new TerminateLog();
			terminateLog.setIsDeleted(CommonConstant.NOT_DELETED);
			terminateLog.setTakenBy(actionTakenBy);
			terminateLog.setTakenDate(new Date());
			terminateLog.setTerminateType(terminateType);
			terminateLog.setTerminateDesc(terminateDesc);
			terminateLog.setTerminateAcctInfo(terminateAcctInfo);
			
			dao.save(terminateLog);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.invoke.method", new Object[]{invMethodName}));
		}
		
	}
	
	public List<TerminateLog> getTerminateLogList()throws BaseException{
		List<TerminateLog> list=new ArrayList<TerminateLog>();
		try{
			list=dao.getTerminateLogList();
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{TerminateLog.class.getSimpleName()}));
		}
		return list;
	}
	
	public void setDao(TerminateHbmDao dao) {
		this.dao = dao;
	}
	public void setMemberDao(MemberHbmDao memberDao) {
		this.memberDao = memberDao;
	}
	public void setAgentDao(AgentHbmDao agentDao) {
		this.agentDao = agentDao;
	}
	
}
